import axios from "axios";
import { saveAs } from "file-saver";
import { getToken, removeToken } from "@/utils/Token";
import { showError } from "@/hooks/use-toast";
import { navigate } from "@/lib/navigation";

// 定义通用的响应数据类型
export interface ApiResponse<T = any> {
  code: number;
  msg: string;
  data: T;
  success: boolean;
}

export interface ApiListResponse<T = any> extends ApiResponse {
  rows: Array<T>;
  total: number;
}

// 验证是否为 blob 数据
const blobValidate = (data: any) => {
  return data instanceof Blob;
};

// 创建 axios 实例
const api = axios.create({
  baseURL: "/videoanalysis",
  timeout: 60000,
  headers: {
    "Content-Type": "application/json",
  },
});

const publicUrls = [
  "/getInfo",
  "/captchaImage",
  "/app/login",
  "/sendSmsCode",
  "/app/reg-and-login",
];

// 请求拦截器
api.interceptors.request.use(
  (config) => {
    // 可以在这里添加 token
    const token = getToken();

    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    } else {
      // 检查当前请求的 URL 是否在公共 URL 列表中
      const isPublicUrl = publicUrls.some(
        (url) => config.url.indexOf(url) !== -1
      );

      if (!isPublicUrl) {
        gotoLogon();
        return Promise.reject(new Error("未授权访问，请先登录"));
      }
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

const gotoLogon = () => {
  const token = getToken();
  showError(token ? "登录已超时，" : "您稍微登录，" + "请先登录操作");
  setTimeout(() => {
    // 取消请求并跳转到登录页
    removeToken();
    navigate("/login", { replace: true });
    // 返回一个 rejected Promise 来取消请求
  }, 500);
};

// 响应拦截器
api.interceptors.response.use(
  (response) => {
    const { data } = response;
    if (data) {
      if (
        data.code === 200 ||
        data.type ==
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      ) {
        return data;
      } else if (data.code === 401) {
        const isPublicUrl = publicUrls.some(
          (url) => response.config.url.indexOf(url) !== -1
        );
        if (!isPublicUrl) {
          // 如果不是公共提示系统权限问题
          gotoLogon();
        }
      } else if (data.code == 500) {
        showError(data.msg, "操作失败");
      }
    }
    return response.data;
  },
  (error) => {
    // 统一错误处理
    if (error.response?.status === 401) {
      // 清除本地存储的用户信息
      localStorage.removeItem("token");
      localStorage.removeItem("user");
      // 重定向到登录页
      window.location.href = "/login";
    }

    return Promise.reject(error.response?.data || error.msg);
  }
);

// API 方法封装
export const apiClient = {
  get: <T = any, R extends ApiResponse<T> = ApiResponse<T>>(
    url: string,
    config?: any
  ): Promise<R> => api.get(url, config),

  post: <T = any, R extends ApiResponse<T> = ApiResponse<T>>(
    url: string,
    data?: any,
    config?: any
  ): Promise<R> => api.post(url, data, config),

  getList: <T = any>(url: string, config?: any): Promise<ApiListResponse<T>> =>
    api.get(url, config),

  // 下载文件方法
  download: (url: string, params = {}, filename: string) => {
    // 直接使用 axios 实例，跳过响应拦截器避免类型问题
    const token = getToken();
    return axios
      .post(url, params, {
        baseURL: "/videoanalysis",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          Authorization: `Bearer ${token}`,
        },
        responseType: "blob",
        timeout: 10000,
      })
      .then(async (response) => {
        const data = response.data;
        const isBlob = blobValidate(data);
        console.info("isBlob", isBlob, filename);
        if (isBlob) {
          const blob = new Blob([data]);
          saveAs(blob, filename);
        } else {
          const resText = await data.text();
          const rspObj = JSON.parse(resText);
          const errMsg = rspObj.msg;
          console.error("下载文件失败:", errMsg);
        }
      })
      .catch((r) => {
        console.error("下载文件出现错误:", r);
      });
  },
};

export default api;
